//
//  CLImageDisplayController.m
//  CLImagePicker
//
//  Created by Criss on 2017/3/27.
//  Copyright © 2017年 Criss. All rights reserved.
//

#import "CLImageDisplayController.h"
#import "CLImagePickerController.h"
#import "CLImageCollectionCell.h"
#import "CLImageShowView.h"
#import "CLImageScrollDisplayView.h"
#import <Photos/Photos.h>
#import "UIImageView+WebCache.h"

#define numOfImagesEveryLine _imagesForRow

@interface CLImageView : UIImageView

@property (nonatomic, strong) UIButton *deleteBtn;

@property (copy, nonatomic) void(^imageViewClick)(CLImageView *imageView);

@end

@implementation CLImageView

- (instancetype) initWithImage:(UIImage *)image {
    if (self = [super initWithImage:image]) {
        [self addAction];
    }
    return self;
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        [self addAction];
    }
    return self;
}

- (void)addAction {
    self.userInteractionEnabled = YES;
    
    if (self.gestureRecognizers.count > 0) {
        for (UIGestureRecognizer *gesture in self.gestureRecognizers) {
            if ([gesture isKindOfClass:[UITapGestureRecognizer class]]) {
                [self removeGestureRecognizer:gesture];
            }
        }
    }
    
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGesture:)];
    [self addGestureRecognizer:tap];
}

- (void)tapGesture:(UITapGestureRecognizer *)tap {
    if (self.imageViewClick) {
        self.imageViewClick((CLImageView *)tap.view);
    }
}

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    UIView *view = [super hitTest:point withEvent:event];
    if (view == nil) {
        CGPoint tempoint = [self.deleteBtn convertPoint:point fromView:self];
        if (CGRectContainsPoint(self.deleteBtn.bounds, tempoint))
        {
            view = self.deleteBtn;
        }
    }
    return view;
}

@end

@interface CLImageDisplayController () <UIImagePickerControllerDelegate, UINavigationControllerDelegate>

@property (weak, nonatomic) UIView *imageShowView;  // 展示图片的view
@property (weak, nonatomic) CLImageView *plusImageView; // 点击添加图片的imageView

@property (strong, nonatomic) NSMutableDictionary *imageDic; // 存储相册相机选择的图片
@property (strong, nonatomic) NSMutableArray *sortArray; // 储存相册相机选择图片的顺序
@property (strong, nonatomic) NSArray *imageArray; //获取的相册图片
@property (assign, nonatomic) CGFloat imageViewHeight; //图片展示视图的高
@property (strong, nonatomic) NSMutableArray *imageViewArrayM; //界面展示的图片
@property (strong, nonatomic) NSMutableArray<UIImage *> *originalImages;  //存储初始化的图片

@end

@implementation CLImageDisplayController {
    UIImageView *_imageView;
}

+ (instancetype)initWithImagesArray:(NSArray<UIImage *> *)images {
    CLImageDisplayController *imageDisplayVC = [[self alloc] init];
    imageDisplayVC.originalImages = images.mutableCopy;
    return imageDisplayVC;
}

// 加载网络图片使用了SDWebImage
+ (instancetype)initWithImageUrls:(NSArray<NSString *> *)imageUrlStrs; {
    CLImageDisplayController *imageDisplayVC = [[self alloc] init];
    [imageDisplayVC loadWebImage:imageUrlStrs];
    return imageDisplayVC;
}

- (void)loadWebImage:(NSArray<NSString *> *)imageUrlStrs {
    NSMutableArray *imagesArrayM = [NSMutableArray array];
    // 调度组
    dispatch_group_t group = dispatch_group_create();
    for (NSString *urlStr in imageUrlStrs) {
        dispatch_group_enter(group);
        
        // SDWebImage加载图片,有需要可以替换为其他加载图片的方法
        [[SDWebImageManager sharedManager] loadImageWithURL:[NSURL URLWithString:urlStr] options:SDWebImageRetryFailed progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {

            [imagesArrayM addObject:image];
            dispatch_group_leave(group);
            
        }];
        
    }
    // 在网络图片加载出来以后赋值，刷新
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        dispatch_async(dispatch_get_main_queue(), ^{
            self.originalImages = imagesArrayM;
            [self reloadImageViewDisplay:imagesArrayM];
        });
    });
}

- (void)setImageUrls:(NSArray<NSString *> *)imageUrls {
    _imageUrls = imageUrls;
    [self loadWebImage:imageUrls];
    self.sortArray = nil;
    self.imageDic = nil;
}

- (instancetype)init {
    if (self = [super init]) {
        [self obtainImageFromPhone];
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    [self createUI];
}

- (void)createUI {
    _imagesForRow = _imagesForRow?:4;
    _imageCounts = _imageCounts?:8;
    self.view.backgroundColor = [UIColor whiteColor];
    
    UIView *imageShowView = [[UIView alloc] initWithFrame:CGRectMake(10,CGRectGetMaxY(self.navigationController.navigationBar.frame) + 10, self.view.bounds.size.width - 20, 100)];
    self.imageShowView = imageShowView;
    [self.view addSubview:imageShowView];

    CLImageView *imageView = [self imagePickView];
    self.plusImageView = imageView;
    imageView.userInteractionEnabled = YES;
    imageView.frame = CGRectMake(10, 10, imageView.frame.size.width, imageView.frame.size.height);
    self.imageViewHeight = imageView.frame.size.height;
    imageView.imageViewClick = ^(CLImageView *imageView) {
        [self addImageTapGesture:imageView];
    };
    
    dispatch_async(dispatch_get_main_queue(), ^{
        [imageShowView addSubview:imageView];
        if (self.originalImages.count > 0 && self.originalImages) {
            [self reloadImageViewDisplay:self.originalImages];
        }else {
            [self reloadImageShowViewHeight:1];
        }
    });
}

// 更新高度
- (void)reloadImageShowViewHeight:(NSInteger)imagaSelectedCounts {
    NSInteger line = imagaSelectedCounts / numOfImagesEveryLine + 1;
    CGRect rect = self.imageShowView.frame;
    rect.size.height = (self.imageViewHeight + 10) * line + 10;
    
    if (self.imageShowView.frame.size.height == rect.size.height) {
        return;
    }
    self.imageShowView.frame = rect;

    if ([self.displayDelegate respondsToSelector:@selector(cl_imageDispaly:imageDisplayViewNewHeight:)]) {
        CGFloat tailing = 10;
//        if (self.autoLayout) {
//            self.view.frame = CGRectZero;
//            self.view.translatesAutoresizingMaskIntoConstraints=NO;
//            [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10-[_imageShowView]-10-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_imageShowView)]];
//            [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-10-[_imageShowView]-tailing-|" options:0 metrics:@{@"tailing": @(tailing)} views:NSDictionaryOfVariableBindings(_imageShowView)]];
//        }
        
        [self.displayDelegate cl_imageDispaly:self imageDisplayViewNewHeight:rect.size.height + 10 + tailing];
    }
}

- (CLImageView *)imagePickView {
    CLImageView *imageView = [[CLImageView alloc] initWithImage:obtainImage(@"plus")];
    CGRect rect = imageView.frame;
    CGFloat width = (self.imageShowView.bounds.size.width - (numOfImagesEveryLine + 1) * 10) / numOfImagesEveryLine;
    rect.size = CGSizeMake(width, width);
    imageView.frame = rect;
    return imageView;
}

#pragma mark - 选择相册或者拍照
/**
 @param sourcePhoto 预留参数
 */
- (void)selectPhotoFrom:(NSString *)sourcePhoto {
    if (!self.imageArray || self.imageArray.count == 0) {
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            [self obtainImageFromPhone];
        });
    }
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
    UIAlertAction *camareAction = [UIAlertAction actionWithTitle:@"拍照" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
    
        if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
            UIImagePickerController *imagePickerVC = [[UIImagePickerController alloc] init];
            imagePickerVC.allowsEditing = YES;
            imagePickerVC.sourceType = UIImagePickerControllerSourceTypeCamera;
            imagePickerVC.delegate = self;
            UIViewController *rootVC = [UIApplication sharedApplication].keyWindow.rootViewController;
            while (rootVC.presentedViewController) {
                rootVC = rootVC.presentedViewController;
            }
            [rootVC presentViewController:imagePickerVC animated:YES completion:nil];
        }
    }];
    
    UIAlertAction *libAction = [UIAlertAction actionWithTitle:@"相册" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        CLImagePickerController *imagePickerController = [CLImagePickerController imagePickerWithImageArray:self.imageArray];
        imagePickerController.isShowImageByScrllView = self.isShowImageByScrllView;
        imagePickerController.imageCounts = _imageCounts;
        imagePickerController.imagesSelectedDic = self.imageDic;
        imagePickerController.imageSortArray = self.sortArray;
        imagePickerController.originalImagesCounts = self.originalImages.count;
        imagePickerController.imageSelectedBlock = ^(NSDictionary *info, NSArray *sortOrder) {
            
            self.imageDic = info.mutableCopy;
            self.sortArray = sortOrder.mutableCopy;
            
            NSMutableArray *imageArrayM = [NSMutableArray arrayWithArray:self.originalImages];
            [sortOrder enumerateObjectsUsingBlock:^(NSString *obj, NSUInteger idx, BOOL * _Nonnull stop) {
                [imageArrayM addObject:info[obj]];
            }];
            [self reloadImageViewDisplay:imageArrayM];

        };
        
        UIViewController *rootVC = [UIApplication sharedApplication].keyWindow.rootViewController;
        while (rootVC.presentedViewController) {
            rootVC = rootVC.presentedViewController;
        }
        
        [rootVC presentViewController:[[UINavigationController alloc] initWithRootViewController:imagePickerController] animated:YES completion:nil];
    }];
    
    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
    
    [alert addAction:camareAction];
    [alert addAction:libAction];
    [alert addAction:cancelAction];
    UIViewController *rootVC = [UIApplication sharedApplication].keyWindow.rootViewController;
    while (rootVC.presentedViewController) {
        rootVC = rootVC.presentedViewController;
    }
    [rootVC presentViewController:alert animated:YES completion:nil];
}

- (void)removeAllImageViews {
    for (UIImageView *imageView in self.imageShowView.subviews) {
        if (![imageView isMemberOfClass:[CLImageView class]]) {
            return;
        }
        if (![imageView isEqual:self.plusImageView]) {
            [imageView removeFromSuperview];;
        }
    }
}

- (void)addImageTapGesture:(CLImageView *)tapGetureView {
    [self selectPhotoFrom:@"Default"];
}

#pragma mark - 重新展示选择好的图片
- (void)reloadImageViewDisplay:(NSMutableArray *)imageArray {
    [self removeAllImageViews];
    [_imageViewArrayM removeAllObjects];
    NSInteger counts = imageArray.count;
    if (counts < _imageCounts) {
        counts ++;
    }

    for (int i = 0; i < counts; i ++) {
        CLImageView *imageView;
        UIButton *deleteBtn;
        if (imageArray.count != i) {
            imageView = [[CLImageView alloc] initWithImage:imageArray[i]];
            imageView.imageViewClick = ^(CLImageView *imageView) {
                [self plusImageViewTap:imageView];
            };
            if (!_imageViewArrayM) {
                _imageViewArrayM = [NSMutableArray array];
            }
            [_imageViewArrayM addObject:imageView];
            imageView.userInteractionEnabled = YES;
            deleteBtn = [UIButton buttonWithType:UIButtonTypeCustom];
            [deleteBtn setImage:obtainImage(@"close") forState:UIControlStateNormal];
            [deleteBtn addTarget:self action:@selector(deleteImage:) forControlEvents:UIControlEventTouchUpInside];
            [deleteBtn sizeToFit];
            imageView.deleteBtn = deleteBtn;
            [imageView addSubview:deleteBtn];
            [self.imageShowView addSubview:imageView];
        }else {
            imageView = self.plusImageView;
            deleteBtn.hidden = YES;
        }
        [self resetImageViewLayout:imageView index:i];
        deleteBtn.center = CGPointMake(self.imageViewHeight, 0);
    }
    self.plusImageView.hidden = !(_imageCounts - imageArray.count);
    [self reloadImageShowViewHeight:imageArray.count];
    
}

// 布局图片
- (void)resetImageViewLayout:(UIImageView *)imageView index:(NSInteger)index{
    imageView.frame = CGRectMake(index % numOfImagesEveryLine * (self.imageViewHeight + 10) + 10, 10 +  index / numOfImagesEveryLine * (self.imageViewHeight + 10), self.imageViewHeight, self.imageViewHeight);
}

// 删除图片
- (void)deleteImage:(UIButton *)sender {
    if ([_imageViewArrayM containsObject:sender.superview]) {
        NSInteger deleteIndex = [_imageViewArrayM indexOfObject:sender.superview];
        if (deleteIndex >= self.originalImages.count) {
            deleteIndex -= self.originalImages.count;
            [self.imageDic removeObjectForKey:self.sortArray[deleteIndex]];
            [self.sortArray removeObjectAtIndex:deleteIndex];
        }else {
            [self.originalImages removeObjectAtIndex:deleteIndex];
        }
        
        [_imageViewArrayM removeObject:sender.superview];
        [sender.superview removeFromSuperview];
        
        [_imageViewArrayM containsObject:self.plusImageView]?:[_imageViewArrayM addObject:self.plusImageView];
        
        for (int i = 0; i < _imageViewArrayM.count; i ++) {
            [UIView animateWithDuration:0.4 animations:^{
                [self resetImageViewLayout:_imageViewArrayM[i] index:i];
            }completion:^(BOOL finished) {
                if (i == _imageViewArrayM.count - 1) {
                    self.plusImageView.hidden = NO;
                    [self reloadImageShowViewHeight:_imageViewArrayM.count - 1];
                }
            }];
        }
    }
    
}

#pragma mark - 图片预览
- (void)plusImageViewTap:(CLImageView *)tapGestureView {
    CGRect imageViewFrame = [self.imageShowView convertRect:tapGestureView.frame toView:[UIApplication sharedApplication].keyWindow];
    UIView *imageShowView;
    if (self.isShowImageByScrllView) {
        imageShowView = [[CLImageScrollDisplayView alloc] initWithConverFrame:imageViewFrame index:[_imageViewArrayM indexOfObject:tapGestureView] willShowImages:[self largeImages]];
        ((CLImageScrollDisplayView *)imageShowView).showPageControl = YES;
        ((CLImageScrollDisplayView *)imageShowView).imageViewWillDismissBlock = ^CGRect(NSIndexPath *indexPath) {
            UIImageView *imageView = _imageViewArrayM[indexPath.row];
            CGRect dismissRect = [self.imageShowView convertRect:imageView.frame toView:[UIApplication sharedApplication].keyWindow];
            return dismissRect;
        };
    }else {
        imageShowView = [[CLImageShowView alloc] initWithImageView:tapGestureView converFrame:imageViewFrame];
    }
    [[UIApplication sharedApplication].keyWindow addSubview:imageShowView];
}

/**
 获取手机相册的照片
 */
- (void)obtainImageFromPhone {
    // 获得相机胶卷
    PHAssetCollection *cameraRoll = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:nil].lastObject;
    [self enumerateAssetsInAssetCollection:cameraRoll original:NO];
}
/**
 * 遍历相簿中的所有图片
 * @param assetCollection 相簿
 * @param original 是否要原图
 */
- (void)enumerateAssetsInAssetCollection:(PHAssetCollection *)assetCollection original:(BOOL)original{
    PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
    options.resizeMode = PHImageRequestOptionsResizeModeFast;
    // 同步获得图片, 只会返回1张图片
    options.synchronous = YES;
    // 获得某个相簿中的所有PHAsset对象
    PHFetchResult<PHAsset *> *assets = [PHAsset fetchAssetsInAssetCollection:assetCollection options:nil];
    NSMutableArray *arrayM = [NSMutableArray array];
    for (PHAsset *asset in assets) {
        // 是否要原图
        CGSize size = original ? CGSizeMake(asset.pixelWidth, asset.pixelHeight) : CGSizeMake([UIScreen mainScreen].bounds.size.width , asset.pixelHeight * [UIScreen mainScreen].bounds.size.width / asset.pixelWidth);
        // 从asset中获得图片
        [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:size contentMode:PHImageContentModeDefault options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
            [arrayM addObject:result];
        }];
    }
    self.imageArray = arrayM.copy;
}

#pragma mark - UIImagePickerControllerDelegate, UINavigationControllerDelegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
    UIImage *image = info[@"UIImagePickerControllerOriginalImage"];
    UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), (__bridge void * _Nullable)(picker));
}

- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
    UIImagePickerController *pickerVC = (__bridge UIImagePickerController *)contextInfo;
    NSMutableArray *imageArrayM = [NSMutableArray arrayWithArray:self.originalImages];
    [self.imageDic setObject:image forKey:@(self.imageArray.count).description];
    [self.sortArray addObject:@(self.imageArray.count).description];
    [self.sortArray enumerateObjectsUsingBlock:^(NSString *obj, NSUInteger idx, BOOL * _Nonnull stop) {
        [imageArrayM addObject:self.imageDic[obj]];
    }];
    [self reloadImageViewDisplay:imageArrayM];
    [pickerVC dismissViewControllerAnimated:YES completion:nil];
    self.imageArray = [self.imageArray arrayByAddingObject:image];
}

#pragma mark - 懒加载
- (NSMutableDictionary *)imageDic {
    if (!_imageDic) {
        _imageDic = [NSMutableDictionary dictionary];
    }
    return _imageDic;
}

- (NSMutableArray *)sortArray {
    if (!_sortArray) {
        _sortArray = [NSMutableArray array];
    }
    return _sortArray;
}

#pragma mark - 获取图片
- (NSArray *)largeImages {
    NSMutableArray *imageArrayM = [NSMutableArray arrayWithArray:self.originalImages];
    [self.sortArray enumerateObjectsUsingBlock:^(NSString *obj, NSUInteger idx, BOOL * _Nonnull stop) {
        [imageArrayM addObject:self.imageDic [obj]];
    }];
    return imageArrayM.copy;
}

- (NSArray *)mediumImages {
    return [self zoomImagesWithRatio:0.5];
}

- (NSArray *)smallImages {
    return [self zoomImagesWithRatio:0.1];
}

- (NSArray *)zoomImagesWithRatio:(CGFloat)ratio {
    NSMutableArray *imageArrayM = [NSMutableArray array];
    for (UIImage *image in self.originalImages) {
        NSData *data = UIImageJPEGRepresentation(image, ratio);
        [imageArrayM addObject:[UIImage imageWithData:data]];
    }
    
    [self.sortArray enumerateObjectsUsingBlock:^(NSString *obj, NSUInteger idx, BOOL * _Nonnull stop) {
        [imageArrayM addObject:[UIImage imageWithData:UIImageJPEGRepresentation(self.imageDic [obj], ratio)]];
    }];
    return imageArrayM.copy;
}

- (NSArray *)imagesData {
    NSMutableArray *imageArrayM = [NSMutableArray array];
    for (UIImage *image in self.originalImages) {
        NSData *data = UIImagePNGRepresentation(image);
        [imageArrayM addObject:data];
    }
    
    [self.sortArray enumerateObjectsUsingBlock:^(NSString *obj, NSUInteger idx, BOOL * _Nonnull stop) {
        [imageArrayM addObject:UIImagePNGRepresentation(self.imageDic [obj])];
    }];
    return imageArrayM.copy;
}

@end
